package com.hua.designpattern.creational.builder;

import java.util.ArrayList;
import java.util.List;

public class TestBuilder {

	/**
	 * 
	 * @author joshua
	 * 
	 *         <pre>
	 * 
	 * 场景
	 * 首先客户程序创建一个指导者对象，一个建造者角色，并将建造者角色传入指导者对象进行配置。
	 * 然后，指导者按照步骤调用建造者的方法创建产品。
	 * 最后客户程序从建造者或者指导者那里得到产品。
	 * 
	 * 建造者模式是将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。
	 * 
	 * 
	 * 1)抽象建造者角色(MealBuilder)：这个角色用来规范产品对象的各个组成成分的建造。一般而言，此角色独立于应用程序的业务逻辑。
	 * 2)具体建造者角色(MealBuilder subCalss)：担任这个角色的是于应用程序紧密相关的类，它们在指导者的调用下创建产品实例。
	 *     这个角色在实现抽象建造者角色提供的方法的前提下，达到完成产品组装，提供成品的功能。
	 * 3)指导者角色(Director)：调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识，真正拥有产品类的具体知识的是具体建造者对象。
	 * 4)产品角色(Meal subClass)：建造中的复杂对象。它要包含那些定义组件的类，包括将这些组件装配成产品的接口。
	 * 
	 * 优点：
	 * 1、Builder模式实现了构建和表示的分离，可以很好的实现解耦。
	 * 
	 * 缺点：
	 * 每次获得对象，必须先创建ConcreteBuilder才能构建对象。
	 * 
	 * Builder模式和抽象工厂模式都能实现创建和展示的分离，都属于创建型模式
	 * Builder模式重在创建过程，相同的构建过程，产生不同的表示。
	 * AbstractFactory模式重在结果，获得工厂在产生对象。
	 * 
	 * REF:
	 *     java.lang.StringBuilder
	 *     java.util.Calendar$Builder
	 * 
	 *         </pre>
	 *
	 *
	 *
	 */

	public static void main(String[] args) {

		List<Drink> drinks = new ArrayList<Drink>();
		drinks.add(new DrinkCold());
		drinks.add(new DrinkHot());
		List<Burger> burgers = new ArrayList<Burger>();
		burgers.add(new BurgerChicken());
		burgers.add(new BurgerVegetable());

		BuilderMeal builderMealBreakfast = new BuilderMealBreakfast();
		Director director1 = new Director(builderMealBreakfast);
		director1.produceMeal(drinks, burgers);
		MealBreakfast breakfast = (MealBreakfast) builderMealBreakfast.getResult();
		System.out.println(breakfast);

		System.out.println("--------");
		System.out.println("--------");

		BuilderMeal builderMealLunch = new BuilderMealLunch();
		Director director2 = new Director(builderMealLunch);
		director2.produceMeal(drinks, burgers);
		MealLunch lunch = (MealLunch) builderMealLunch.getResult();
		System.out.println(lunch);

		System.out.println("--------");
		System.out.println("--------");

		BuilderMeal builderMealDinner = new BuilderMealDinner();
		Director director3 = new Director(builderMealDinner);
		director3.produceMeal(drinks, burgers);
		MealDinner dinner = (MealDinner) builderMealDinner.getResult();
		System.out.println(dinner);

	}

}
